package module.StoreService.Impl;

import common.model.Entity.StoreEntity.CartItem;
import common.model.Entity.StoreEntity.Product;
import dao.StoreDao.CartItemDao;
import dao.StoreDao.ProductDao;
import dao.impl.StoreDaoImpl.CartItemDaoImpl;
import dao.impl.StoreDaoImpl.ProductDaoImpl;
import module.StoreService.CartItemService;
import network.protocol.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Optional;

/**
 * {@code CartItemServiceImpl} 是 {@link CartItemService} 的实现类，
 * 提供购物车项的增删改查以及统计功能。
 * <p>
 * 主要实现逻辑：
 * <ul>
 *     <li>通过 {@link CartItemDao} 操作购物车项数据</li>
 *     <li>通过 {@link ProductDao} 获取商品信息</li>
 *     <li>所有操作结果均封装在 {@link Response} 中返回</li>
 *     <li>错误和异常通过 {@link Logger} 进行日志记录</li>
 * </ul>
 * <p>
 * 使用了单例模式，推荐通过 {@link #getInstance()} 获取实例。
 */
public class CartItemServiceImpl implements CartItemService {
    private static final Logger logger = LoggerFactory.getLogger(CartItemServiceImpl.class);
    private final CartItemDao cartItemDao = new CartItemDaoImpl();
    private final ProductDao productDao = new ProductDaoImpl();

    /** 单例实例 */
    private static final CartItemServiceImpl INSTANCE = new CartItemServiceImpl();

    /**
     * 获取 {@code CartItemServiceImpl} 单例对象。
     *
     * @return 单例实例
     */
    public static CartItemServiceImpl getInstance() {
        return INSTANCE;
    }

    /** 默认构造函数 */
    public CartItemServiceImpl() {}

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<List<CartItem>> getCartItemsByCartId(long cartId) {
        try {
            List<CartItem> items = cartItemDao.findByCart(cartId);
            return Response.success(items);
        } catch (Exception e) {
            logger.error("获取购物车项失败: cartId={}", cartId, e);
            return Response.error("获取购物车项失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Optional<CartItem>> getCartItemByCartAndProduct(long cartId, long productId) {
        try {
            Optional<CartItem> item = cartItemDao.findByCartAndProduct(cartId, productId);
            return Response.success(item);
        } catch (Exception e) {
            logger.error("获取购物车项失败: cartId={}, productId={}", cartId, productId, e);
            return Response.error("获取购物车项失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> addToCart(long cartId, long productId, int quantity) {
        try {
            if (quantity <= 0) {
                logger.warn("添加到购物车失败: 数量必须大于0, cartId={}, productId={}, quantity={}",
                        cartId, productId, quantity);
                return Response.error("数量必须大于0");
            }

            // 获取商品信息
            Optional<Product> productOpt = productDao.findById(productId);
            if (productOpt.isEmpty()) {
                logger.warn("添加到购物车失败: 商品不存在, productId={}", productId);
                return Response.error("商品不存在");
            }
            Product product = productOpt.get();
            double price = product.getPrice();

            // 检查是否已存在相同商品的购物车项
            Optional<CartItem> existingItem = cartItemDao.findByCartAndProduct(cartId, productId);

            if (existingItem.isPresent()) {
                // 已存在则更新数量
                CartItem item = existingItem.get();
                item.setQuantity(item.getQuantity() + quantity);
                // 根据业务需求，不更新价格，保持添加时的价格
                boolean result = cartItemDao.update(item);
                return result ? Response.success(true) : Response.error("更新购物车项失败");
            } else {
                // 不存在则创建新项
                CartItem newItem = new CartItem();
                newItem.setCartId(cartId);
                newItem.setProductId(productId);
                newItem.setQuantity(quantity);
                newItem.setPrice(price); // 设置当前商品价格

                boolean result = cartItemDao.save(newItem);
                return result ? Response.success(true) : Response.error("添加购物车项失败");
            }
        } catch (Exception e) {
            logger.error("添加到购物车失败: cartId={}, productId={}, quantity={}",
                    cartId, productId, quantity, e);
            return Response.error("添加到购物车失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> updateCartItemQuantity(long cartItemId, int quantity) {
        try {
            if (quantity <= 0) {
                // 数量为0或负数时，直接删除该项
                return removeFromCart(cartItemId);
            }

            Optional<CartItem> item = cartItemDao.findById(cartItemId);
            if (item.isEmpty()) {
                logger.warn("更新购物车项数量失败: 未找到ID为 {} 的购物车项", cartItemId);
                return Response.error("未找到购物车项");
            }

            CartItem cartItem = item.get();
            cartItem.setQuantity(quantity);
            boolean result = cartItemDao.update(cartItem);
            return result ? Response.success(true) : Response.error("更新购物车项数量失败");
        } catch (Exception e) {
            logger.error("更新购物车项数量失败: cartItemId={}, quantity={}", cartItemId, quantity, e);
            return Response.error("更新购物车项数量失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Boolean> removeFromCart(long cartItemId) {
        try {
            boolean result = cartItemDao.deleteById(cartItemId);
            return result ? Response.success(true) : Response.error("删除购物车项失败");
        } catch (Exception e) {
            logger.error("从购物车移除商品失败: cartItemId={}", cartItemId, e);
            return Response.error("从购物车移除商品失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Integer> getCartItemCount(long cartId) {
        try {
            List<CartItem> items = cartItemDao.findByCart(cartId);
            int count = items.stream().mapToInt(CartItem::getQuantity).sum();
            return Response.success(count);
        } catch (Exception e) {
            logger.error("获取购物车商品总数失败: cartId={}", cartId, e);
            return Response.error("获取购物车商品总数失败: " + e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Response<Double> getCartTotalAmount(long cartId) {
        try {
            List<CartItem> items = cartItemDao.findByCart(cartId);
            double total = items.stream()
                    .mapToDouble(item -> item.getPrice() * item.getQuantity())
                    .sum();
            return Response.success(total);
        } catch (Exception e) {
            logger.error("获取购物车总金额失败: cartId={}", cartId, e);
            return Response.error("获取购物车总金额失败: " + e.getMessage());
        }
    }
}
